<template>
    <tnxel-alert class="mb-0" type="error" v-if="message">{{ message }}</tnxel-alert>
    <el-tree ref="tree"
        class="border py-1"
        :data="dataList"
        node-key="id"
        :default-expanded-keys="expandedIds"
        :expand-on-click-node="false"
        :empty-text="dataList === null ? '加载中...' : undefined"
        v-else>
        <template #default="{data, node}">
            <div class="flex-1 flex-v-center">
                <div class="flex-v-center flex-1"
                    @click="toggleNodeExpanded(node)"
                    @dblclick="toOpenClass(node, true)"
                >
                    <NodeIcon class="me-1" :type="data.kind.toString()"/>
                    <span class="text-secondary" v-if="data.packageName">{{ data.packageName }}.</span>
                    <span :class="{'abstract-class-name': data.abstractClass, 'strong': data.id === classId}">
                        {{ data.simpleName }}
                    </span>
                    <span class="text-placeholder ms-1" v-if="data.caption">({{ data.caption }})</span>
                </div>
                <tnxel-button type="primary"
                    class="me-2"
                    link
                    icon="Reading"
                    tooltip="打开"
                    @click="toOpenClass(node)"
                    v-if="data instanceof ModelingClass && open"/>
            </div>
        </template>
    </el-tree>
</template>

<script>
import tnx from '@/tnx';
import ModelingClass from '@/logic/modeling/entity/ModelingClass.js';

import NodeIcon from './components/NodeIcon.vue';

export default {
    components: {NodeIcon},
    props: {
        classId: {
            type: String,
            required: true,
        },
        open: Function,
    },
    data() {
        return {
            message: null,
        };
    },
    computed: {
        ModelingClass() {
            return ModelingClass;
        },
        project() {
            return tnx.app.global.modelingProject;
        },
        dataList() {
            let root = this.project.findClass(null, 'java.lang.Object', true);
            if (root) {
                root = root.origin.clone();
                let children = [];
                root.children = children;
                let clazz = this.project.findClass(null, this.classId, true);
                if (!clazz) {
                    this.message = '找不到类：' + this.classId;
                } else {
                    clazz = clazz.clone();
                    this.message = null;
                    let classChain = this.project.getSuperClassChain(clazz, true, true);
                    for (let c of classChain) {
                        let appName = c.appName;
                        c = c.clone();
                        c.appName = appName;
                        children.push(c);
                        children = [];
                        c.children = children;
                    }
                    children.push(...this.project.getSubClassTree(clazz, 'children'));
                }
                return [root];
            }
            return null;
        },
        expandedIds() {
            let ids = [];
            const fillExpandedIds = function (data) {
                if (data.children.length) {
                    ids.push(data.id);
                    for (let child of data.children) {
                        fillExpandedIds(child);
                    }
                }
            }
            if (this.dataList) {
                fillExpandedIds(this.dataList[0]);
            }
            return ids;
        },
    },
    methods: {
        dialog() {
            return {
                title: '继承层次',
                width: 400,
                buttonText: '关闭',
            }
        },
        toggleNodeExpanded(node) {
            if (node.data.children.length) {
                node.expanded = !node.expanded;
            }
        },
        toOpenClass(node, close) {
            if (this.open) {
                let clazz = node.data;
                this.open(clazz.appName, clazz);
                if (close) {
                    this.$root.close();
                }
            }
        },
    }
}
</script>

<style lang="scss" scoped>
.el-tree {
    height: 256px;

    :deep(.el-tree-node__content) {
        .el-button {
            visibility: hidden;
        }
    }

    :deep(.el-tree-node__content):hover {
        .el-button {
            visibility: visible;
        }
    }
}
</style>
